package com.example.android.trackmysleepquality.sleeptracker

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.android.trackmysleepquality.R
import com.example.android.trackmysleepquality.database.SleepNight
import com.example.android.trackmysleepquality.databinding.ListItemSleepNightBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

private val ITEM_VIEW_TYPE_HEADER = 0
private val ITEM_VIEW_TYPE_ITEM = 1
class SleepNightAdapter(val clickListener: SleepNightListener) :
        ListAdapter<DataItem, RecyclerView.ViewHolder>(SleepNightDiffCallback()) {

    /** 使用协程 */
    private val adapterScope = CoroutineScope(Dispatchers.Default)

    /**
     * 使用DiffUtil刷新列表内容
     */
    class SleepNightDiffCallback : DiffUtil.ItemCallback<DataItem>() {
        //        // 判断oldItem和newItem是否相同
        //        override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
        //            return oldItem.nightId == newItem.nightId
        //        }
        //
        //        // oldItem、newItem是否包含两个相同的数据
        //        override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
        //            return oldItem == newItem
        //        }
        override fun areItemsTheSame(oldItem: DataItem, newItem: DataItem): Boolean {
            return oldItem.id == newItem.id
        }

        @SuppressLint("DiffUtilEquals")
        override fun areContentsTheSame(oldItem: DataItem, newItem: DataItem): Boolean {
            return oldItem == newItem
        }
    }

    /**
     * notifyDataSetChanged()触发列表刷新
     * notifyDataSetChanged效率低下
     */
    //    var data = listOf<SleepNight>()
    //        set(value) {
    //            field = value
    //            notifyDataSetChanged()
    //        }

    // 第一步，使用binding class作为root layout
    // 更改ViewHolder类的签名，以便构造函数是私有的 private constructor
    class ItemViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root) {

        fun bind(item: SleepNight?, clickListener: SleepNightListener) {
            binding.sleep = item
            binding.clickListener = clickListener
            //  此调用是一种优化，它要求数据绑定立即执行所有未决的绑定。
            //  executePendingBindings() 在中使用绑定适配器时 ， 始终最好调用RecyclerView它 ， 因为它可以稍微加快视图的大小 。
            binding.executePendingBindings()
        }

        companion object {
            fun from(parent: ViewGroup): ItemViewHolder {
                val layoutInflater = LayoutInflater.from(parent.context)
                val binding = ListItemSleepNightBinding.inflate(layoutInflater, parent, false)
                return ItemViewHolder(binding)
            }
        }
    }

    // 第二步，inflate内容并返回ItemViewHolder
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        //        val layoutInflater = LayoutInflater.from(parent.context)
        //        val view = layoutInflater.inflate(R.layout.text_item_view, parent, false) as TextView
        // return ItemViewHolder.from(parent)
        return when (viewType) {
            ITEM_VIEW_TYPE_HEADER -> TextViewHolder.from(parent)
            ITEM_VIEW_TYPE_ITEM -> ItemViewHolder.from(parent)
            else -> throw ClassCastException("Unknown viewType ${viewType}")
        }
    }


    // 第三步，直接使用了
//    override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
//        // val item = data[position]
//       val item = getItem(position)
//        // 绑定视图
//        holder.bind(item!!, clickListener)
//
//    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is ItemViewHolder -> {
                val nightItem = getItem(position) as DataItem.SleepNightItem
                holder.bind(nightItem.sleepNight, clickListener)
            }
        }
    }

    override fun getItemViewType(position: Int): Int {
        return when (getItem(position)) {
            is DataItem.Header -> ITEM_VIEW_TYPE_HEADER
            is DataItem.SleepNightItem -> ITEM_VIEW_TYPE_ITEM
        }
    }

    /**
     * 启动协程adapterScope以操作列表
     * 切换到Dispatchers.Main上下文以提交列表
     */
    fun addHeaderAndSubmitList(list: List<SleepNight>) {
        adapterScope.launch {
            val items = when(list) {
                null -> listOf(DataItem.Header)
                else -> listOf(DataItem.Header) + list.map { DataItem.SleepNightItem(it) }
            }
            withContext(Dispatchers.Main) {
                submitList(items)
            }
        }
        // submitList(items)
    }

    //    override fun getItemCount(): Int {
//        return data.size
//    }

//    private fun ItemViewHolder.bind(item: SleepNight) {
    // val res = itemView.context.resources
//        binding.sleep = item
    // 此调用是一种优化，它要求数据绑定立即执行所有未决的绑定。
    // executePendingBindings()在中使用绑定适配器时，始终最好调用RecyclerView它，因为它可以稍微加快视图的大小。
//        binding.executePendingBindings()
//        listItemSleepNightBinding.sleepLength.text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, res)
//        listItemSleepNightBinding.qualityString.text = convertNumericQualityToString(item.sleepQuality, res)
//        listItemSleepNightBinding.qualityImage.setImageResource(
//                when (item.sleepQuality) {
//                    0 -> R.drawable.ic_sleep_0
//                    1 -> R.drawable.ic_sleep_1
//                    2 -> R.drawable.ic_sleep_2
//                    3 -> R.drawable.ic_sleep_3
//                    4 -> R.drawable.ic_sleep_4
//                    else -> R.drawable.ic_sleep_5
//                }
//        )
//    }



}

class TextViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    companion object {
        fun from(parent: ViewGroup): TextViewHolder {
            val layoutInflater = LayoutInflater.from(parent.context)
            val view = layoutInflater.inflate(R.layout.header, parent, false)
            return TextViewHolder(view)
        }
    }
}

/**
 * 点击监听
 */
class SleepNightListener(val clickListener: (sleepId: Long) -> Unit) {
    fun onClick(night: SleepNight) = clickListener(night.nightId)
}
/**
 * sealed定义了一个封闭的类型
 */
sealed class DataItem {
    /**
     * 当适配器用于DiffUtil确定某个项目是否以及如何更改时，DiffItemCallback需要知道每个项目的ID
     */
    abstract val id: Long

    data class SleepNightItem(val sleepNight: SleepNight) : DataItem() {
        override val id: Long
            get() = sleepNight.nightId
    }

    object Header : DataItem() {
        override val id: Long
            get() = Long.MIN_VALUE
    }
}
